package glpm

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
)

// OnlineManagerNames 支持的在线包管理器名称
var OnlineManagerNames = []string{"apt", "yum", "dnf", "apk", "zypper", "pacman"}

// OfflineManagerNames 支持的离线包管理器名称
var OfflineManagerNames = []string{"dpkg", "rpm"}

// ManagerFactory 包管理器工厂
type ManagerFactory struct{}

// NewManagerFactory 创建新的包管理器工厂
func NewManagerFactory() *ManagerFactory {
	return &ManagerFactory{}
}

// CreateManager 创建包管理器实例
func (f *ManagerFactory) CreateManager(config *ManagerConfig) (PackageManager, error) {
	if config == nil {
		config = NewManagerConfig()
	}

	// 如果指定了优先使用的包管理器，尝试创建该管理器
	if config.PreferredName != "" {
		manager, err := f.createSpecificManager(config.PreferredName, config)
		if err == nil && manager.IsAvailable() {
			return manager, nil
		}
	}

	// 自动检测可用的包管理器
	return f.AutoDetectManager(config)
}

// AutoDetectManager 自动检测可用的包管理器
func (f *ManagerFactory) AutoDetectManager(config *ManagerConfig) (PackageManager, error) {
	if config == nil {
		config = NewManagerConfig()
	}

	var managerNames []string

	switch config.ManagerType {
	case OnlineManagerType:
		managerNames = OnlineManagerNames
	case OfflineManagerType:
		managerNames = OfflineManagerNames
	default:
		return nil, fmt.Errorf("不支持的包管理器类型: %s", config.ManagerType)
	}

	// 按优先级顺序检测包管理器
	for _, managerName := range managerNames {
		manager, err := f.createSpecificManager(managerName, config)
		if err == nil && manager.IsAvailable() {
			return manager, nil
		}
	}

	return nil, fmt.Errorf("未检测到可用的 %s 包管理器", config.ManagerType)
}

// createSpecificManager 创建特定的包管理器
func (f *ManagerFactory) createSpecificManager(managerName string, config *ManagerConfig) (PackageManager, error) {
	switch strings.ToLower(managerName) {
	case "apt":
		return NewAptManager(config), nil
	case "yum":
		return NewYumManager(config), nil
	case "dnf":
		return NewDnfManager(config), nil
	case "apk":
		return NewApkManager(config), nil
	case "dpkg":
		return NewDpkgManager(config), nil
	case "rpm":
		return NewRpmManager(config), nil
	case "zypper":
		return NewZypperManager(config), nil
	case "pacman":
		return NewPacmanManager(config), nil
	default:
		return nil, fmt.Errorf("不支持的包管理器: %s", managerName)
	}
}

// ListAvailableManagers 列出系统中可用的包管理器
func (f *ManagerFactory) ListAvailableManagers() []string {
	var available []string

	// 检查在线包管理器
	for _, name := range OnlineManagerNames {
		if isCommandAvailable(name) {
			available = append(available, name)
		}
	}

	// 检查离线包管理器
	for _, name := range OfflineManagerNames {
		if isCommandAvailable(name) {
			available = append(available, name)
		}
	}

	return available
}

// isCommandAvailable 检查命令是否可用
func isCommandAvailable(name string) bool {
	_, err := exec.LookPath(name)
	return err == nil
}

// DetectLinuxDistribution 检测Linux发行版
func (f *ManagerFactory) DetectLinuxDistribution() string {
	// 检查 /etc/os-release 文件
	if _, err := os.Stat("/etc/os-release"); err == nil {
		content, err := os.ReadFile("/etc/os-release")
		if err == nil {
			lines := strings.Split(string(content), "\n")
			for _, line := range lines {
				if strings.HasPrefix(line, "ID=") {
					id := strings.TrimPrefix(line, "ID=")
					id = strings.Trim(id, `"`)
					return id
				}
			}
		}
	}

	// 检查其他发行版标识文件
	distributionFiles := map[string]string{
		"/etc/debian_version": "debian",
		"/etc/redhat-release": "redhat",
		"/etc/centos-release": "centos",
		"/etc/fedora-release": "fedora",
		"/etc/arch-release":   "arch",
		"/etc/alpine-release": "alpine",
		"/etc/SuSE-release":   "suse",
		"/etc/gentoo-release": "gentoo",
	}

	for file, distro := range distributionFiles {
		if _, err := os.Stat(file); err == nil {
			return distro
		}
	}

	return "unknown"
}

// GetRecommendedManager 根据发行版推荐包管理器
func (f *ManagerFactory) GetRecommendedManager() string {
	distro := f.DetectLinuxDistribution()

	switch distro {
	case "debian", "ubuntu":
		return "apt"
	case "centos", "redhat", "fedora":
		return "dnf"
	case "alpine":
		return "apk"
	case "arch":
		return "pacman"
	case "opensuse", "suse":
		return "zypper"
	default:
		return ""
	}
}
